Skip to content

Conversation

@m-a-king
Copy link
Collaborator

@m-a-king m-a-king commented Dec 1, 2024

resolved:

📌 과제 설명

기관 로그인을 구현했습니다.

Spring Security의 UsernamePasswordAuthenticationFilter를 확장하여 ID와 PW 기반의 인증 흐름을 처리하도록 설계했습니다.

👩‍💻 요구 사항과 구현 내용

  1. IdPwAuthFilter 구현

    • UsernamePasswordAuthenticationFilter를 상속받아 기관 로그인 전용 필터 구현.
    • form-data 형식으로 ID와 PW를 받아 AuthenticationManager를 통해 인증.
    • 인증 성공 시 쿠키 설정, 실패 시 ProblemDetail 형식의 에러 응답 처리.
  2. CustomAuthenticationProvider 구현

    • 기관 계정의 인코딩된 비밀번호를 데이터베이스에서 조회하여 비밀번호 검증.
    • 검증 성공 시 JwtAuthenticationToken 반환.
  3. SecurityConfig 수정

    • IdPwAuthFilter를 SecurityConfig에서 직접 생성 및 추가.
    • 순환 참조 문제 해결을 위해 필터를 @Component로 관리하지 않고 명시적으로 생성.
  4. JWT 기반 인증 확장

    • 기존 Volunteer 전용 JWT 생성 로직을 Center 계정에서도 사용할 수 있도록 확장.
    • 인증 성공 시 AccessToken을 쿠키에 설정.
  5. 예외 처리

    • 인증 실패 시 ProblemDetail 형식의 JSON 응답을 반환.
    • JwtExceptionFilter를 수정하여 예외 처리의 일관성을 유지.

인증 흐름

  1. IdPwAuthFilter에서 인증 요청 처리:

    • 클라이언트가 /api/center/sign-in 엔드포인트에 ID와 PW를 전송합니다.
    • IdPwAuthFilterattemptAuthentication 메서드가 호출되며, 요청에서 ID와 PW를 추출하여 UsernamePasswordAuthenticationToken으로 래핑합니다.
    • 이 토큰을 AuthenticationManager.authenticate()에 전달합니다.
  2. AuthenticationManager의 역할:

    • AuthenticationManager는 등록된 여러 AuthenticationProvidersupports() 메서드에 의해 적합한 AuthenticationProvider를 선택합니다.
    • CustomAuthenticationProviderUsernamePasswordAuthenticationToken을 지원하기 때문에 호출됩니다.
  3. CustomAuthenticationProvider에서 인증 처리:

    • CustomAuthenticationProvider.authenticate()가 호출되어 인증 로직을 실행합니다.
    • CenterSignUseCase를 통해 DB에서 인코딩된 비밀번호를 가져오고, PasswordEncoder를 사용하여 입력된 비밀번호를 검증합니다.
    • 인증이 성공하면, JwtAuthenticationToken을 생성하여 반환합니다.
    • 실패 시 BadCredentialsException과 같은 예외를 던집니다.
  4. IdPwAuthFilter로 결과 반환:

    • 성공 시 반환된 JwtAuthenticationToken은 Spring Security 컨텍스트에 저장되며, 이후 요청에서 인증된 사용자 정보로 활용됩니다.
    • 실패 시 IdPwAuthFilterunsuccessfulAuthentication 메서드가 호출되어 예외를 처리하고 클라이언트에 적절한 응답을 반환합니다.

✅ PR 포인트 & 궁금한 점

SecurityConfig의 IdPwAuthFilter 생성 방식이 적절한지 검토 부탁드립니다.

  • IdPwAuthFilter를 직접 생성하는 방식으로 순환 참조 문제를 해결했습니다.
  • SecurityConfigAuthenticationConfiguration으로부터 AuthenticationManager를 제공받기 때문에, Bean으로 명시된 authenticationManager와 순환 참조 문제는 무관합니다.

- 사용자 이름과 비밀번호 인증을 처리하는 IdPwAuthFilter 구현
- attemptAuthentication에서 account_id와 account_password를 기반으로 인증 처리
- 인증 성공 시:
  - GenerateTokensOnLoginUseCase를 사용하여 액세스 토큰 생성
  - CookieUseCase를 통해 액세스 토큰을 쿠키에 설정
- 인증 실패 시:
  - ProblemDetail을 생성하여 표준화된 에러 응답 작성
  - 디버깅을 위한 에러 로그 기록
  - 클라이언트 호환성을 위한 응답 인코딩 및 Content-Type 설정 보장
…ation 처리 커스텀

- CenterSignUseCase를 사용하여 계정 ID로 센터 ID와 인코딩된 비밀번호 조회
- PasswordEncoder로 비밀번호 검증 후, JwtUseCase를 통해 액세스 토큰 생성
- UsernamePasswordAuthenticationToken 인증 성공 시 JwtAuthenticationToken 반환
- authenticationManager Bean 명시적 처리
- passwordEncoder Bean 추가
- idPwAuthFilter의 필터 경로 설정 및 SecurityConfig에서 생성 후 사용
- idPwAuthFilter 의존성 주입 처리
  - authenticationManager와의 순환 참조 문제 해결을 위해 idPwAuthFilter를 Component로 관리하지 않고 SecurityConfig에서 직접 생성
@m-a-king m-a-king self-assigned this Dec 1, 2024
@m-a-king m-a-king linked an issue Dec 1, 2024 that may be closed by this pull request
2 tasks
- 부모가 equals를 오버라이딩하면 자식도 해야함
- 소나가 알려줌
Copy link
Collaborator

@leebs0521 leebs0521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨씁니다.

저도 저번 플젝때 시큐리티, 필터 컴포넌트로 등록안하고 생성해서 사용했었습니다.

Copy link
Collaborator

@ayoung-dev ayoung-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@m-a-king m-a-king added the 재중 label Dec 2, 2024
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 2, 2024

@m-a-king m-a-king merged commit a9f5743 into main Dec 2, 2024
2 checks passed
@m-a-king m-a-king deleted the feature/104-add-center-login branch December 2, 2024 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] 기관 로그인 기능

4 participants